﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Configuration;
using TPOJ.BLL;
using TPOJ.Model;
using System.Web.Caching;
using TPOJ.CacheDependencyFactory;

namespace TPOJ.Web
{
    public static class SolutionDataProxy
    {
        private static readonly int problemTimeout = int.Parse(ConfigurationManager.AppSettings["SolutionCacheDuration"]);
        private static readonly bool enableCaching = bool.Parse(ConfigurationManager.AppSettings["EnableCaching"]);

        public static IList<Solution> GetAllSolutions()
        {
            SolutionBO solutionBO = new SolutionBO();

            if (!enableCaching)
                return solutionBO.GetAllSolutions();

            string key = "solution_all";
            IList<Solution> data = (IList<Solution>)HttpRuntime.Cache[key];

            if (data == null)
            {
                data = solutionBO.GetAllSolutions();

                AggregateCacheDependency aggrCacheDependency = DependencyFacade.GetSolutionDependency();

                HttpRuntime.Cache.Add(key, data, aggrCacheDependency, DateTime.Now.AddHours(problemTimeout), Cache.NoSlidingExpiration, CacheItemPriority.High, null);
            }
            return data;
        }

        public static IList<Solution> GetContestSolutions(int contestId)
        {
            SolutionBO solutionBO = new SolutionBO();

            if (!enableCaching)
                return solutionBO.GetContestSolutions(contestId);

            string key = "solutions_contest" + contestId ;
            IList<Solution> data = (IList<Solution>)HttpRuntime.Cache[key];

            if (data == null)
            {
                data = solutionBO.GetContestSolutions(contestId);

                AggregateCacheDependency aggrCacheDependency = DependencyFacade.GetSolutionDependency();

                HttpRuntime.Cache.Add(key, data, aggrCacheDependency, DateTime.Now.AddHours(problemTimeout), Cache.NoSlidingExpiration, CacheItemPriority.High, null);
            }
            return data;
        }

        public static IList<Solution> GetProblemSolutions(int problemId)
        {
            SolutionBO solutionBO = new SolutionBO();

            if (!enableCaching)
                return solutionBO.GetProblemSolutions(problemId);

            string key = "solutions_problem" + problemId;
            IList<Solution> data = (IList<Solution>)HttpRuntime.Cache[key];

            if (data == null)
            {
                data = solutionBO.GetProblemSolutions(problemId);

                AggregateCacheDependency aggrCacheDependency = DependencyFacade.GetSolutionDependency();

                HttpRuntime.Cache.Add(key, data, aggrCacheDependency, DateTime.Now.AddHours(problemTimeout), Cache.NoSlidingExpiration, CacheItemPriority.High, null);
            }
            return data;
        }

        public static IList<int> GetSolvedProblemIdsByUser(int userId)
        {
            SolutionBO solutionBO = new SolutionBO();

            if (!enableCaching)
                return solutionBO.GetSolvedProblemIdsByUser(userId);

            string key = "solved_problemIds_by" + userId;
            IList<int> data = (IList<int>)HttpRuntime.Cache[key];

            if (data == null)
            {
                data = solutionBO.GetSolvedProblemIdsByUser(userId);

                AggregateCacheDependency aggrCacheDependency = DependencyFacade.GetSolutionDependency();

                HttpRuntime.Cache.Add(key, data, aggrCacheDependency, DateTime.Now.AddHours(problemTimeout), Cache.NoSlidingExpiration, CacheItemPriority.High, null);
            }
            return data;
        }

        public static IList<int> GetTriedNotACedProblemIdsByUser(int userId)
        {
            SolutionBO solutionBO = new SolutionBO();

            if (!enableCaching)
                return solutionBO.GetTriedNotACedProblemIdsByUser(userId);

            string key = "tried_problemIds_by" + userId;
            IList<int> data = (IList<int>)HttpRuntime.Cache[key];

            if (data == null)
            {
                data = solutionBO.GetTriedNotACedProblemIdsByUser(userId);

                AggregateCacheDependency aggrCacheDependency = DependencyFacade.GetSolutionDependency();

                HttpRuntime.Cache.Add(key, data, aggrCacheDependency, DateTime.Now.AddHours(problemTimeout), Cache.NoSlidingExpiration, CacheItemPriority.High, null);
            }
            return data;
        }

        internal static object GetSolvedProblemIdsByUserInContest(int userId, int contestId)
        {

            SolutionBO solutionBO = new SolutionBO();

            if (!enableCaching)
                return solutionBO.GetSolvedProblemIdsByUserInContest(userId, contestId);

            string key = "solved_problemIds_by" + userId;
            IList<int> data = (IList<int>)HttpRuntime.Cache[key];

            if (data == null)
            {
                data = solutionBO.GetSolvedProblemIdsByUserInContest(userId, contestId);

                AggregateCacheDependency aggrCacheDependency = DependencyFacade.GetSolutionDependency();

                HttpRuntime.Cache.Add(key, data, aggrCacheDependency, DateTime.Now.AddHours(problemTimeout), Cache.NoSlidingExpiration, CacheItemPriority.High, null);
            }
            return data;
        }

        internal static object GetTriedNotACedProblemIdsByUserInContest(int userId, int contestId)
        {
            SolutionBO solutionBO = new SolutionBO();

            if (!enableCaching)
                return solutionBO.GetTriedNotACedProblemIdsByUserInContest(userId, contestId);

            string key = "tried_problemIds_by" + userId;
            IList<int> data = (IList<int>)HttpRuntime.Cache[key];

            if (data == null)
            {
                data = solutionBO.GetTriedNotACedProblemIdsByUserInContest(userId, contestId);

                AggregateCacheDependency aggrCacheDependency = DependencyFacade.GetSolutionDependency();

                HttpRuntime.Cache.Add(key, data, aggrCacheDependency, DateTime.Now.AddHours(problemTimeout), Cache.NoSlidingExpiration, CacheItemPriority.High, null);
            }
            return data;
        }
    }
}
